//
//  ZLAntiShakeSwitch.m
//  PersonalOCTest
//
//  防呆UISwitch，支持单个开关防抖和全局开关互斥
//

#import "ZLAntiShakeSwitch.h"

// 全局静态变量，记录最后一次任意开关的操作时间
static NSTimeInterval s_lastGlobalActionTime = 0;

@interface ZLAntiShakeSwitch ()

/// 记录当前开关最后一次操作时间
@property (nonatomic, assign) NSTimeInterval lastActionTime;

/// 是否正在处理值变化事件，防止递归
@property (nonatomic, assign) BOOL isHandlingValueChange;

@end

@implementation ZLAntiShakeSwitch

#pragma mark - 初始化方法

- (instancetype)init {
    self = [super init];
    if (self) {
        [self commonInit];
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self commonInit];
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)coder {
    self = [super initWithCoder:coder];
    if (self) {
        [self commonInit];
    }
    return self;
}

+ (instancetype)switchWithIdentifier:(NSString *)identifier {
    ZLAntiShakeSwitch *antiShakeSwitch = [[ZLAntiShakeSwitch alloc] init];
    antiShakeSwitch.switchIdentifier = identifier;
    return antiShakeSwitch;
}

- (void)commonInit {
    // 设置默认值
    self.antiShakeInterval = 1.0; // 默认1秒防抖间隔
    self.enableGlobalMutex = YES; // 默认启用全局互斥
    self.lastActionTime = 0;
    self.isHandlingValueChange = NO;
    
    // 添加值变化监听
    [self addTarget:self action:@selector(handleValueChanged:) forControlEvents:UIControlEventValueChanged];
}

#pragma mark - 重写父类方法

- (void)sendActionsForControlEvents:(UIControlEvents)controlEvents {
    // 只对UIControlEventValueChanged事件进行防呆处理
    if (controlEvents & UIControlEventValueChanged) {
        if ([self shouldAllowAction]) {
            // 更新时间戳
            [self updateActionTime];
            // 允许执行原有逻辑
            [super sendActionsForControlEvents:controlEvents];
        } else {
            // 防呆拦截：恢复开关状态但不触发事件
            self.isHandlingValueChange = YES;
            self.on = !self.on; // 恢复到之前的状态
            self.isHandlingValueChange = NO;
            
            // 可选：添加视觉反馈提示用户操作过于频繁
            [self showAntiShakeFeedback];
        }
    } else {
        // 其他事件正常处理
        [super sendActionsForControlEvents:controlEvents];
    }
}

#pragma mark - 私有方法

/// 判断是否允许执行操作
- (BOOL)shouldAllowAction {
    if (self.isHandlingValueChange) {
        return NO; // 防止递归
    }
    
    NSTimeInterval currentTime = [[NSDate date] timeIntervalSince1970];
    
    // 检查单个开关防抖
    if (currentTime - self.lastActionTime < self.antiShakeInterval) {
        return NO;
    }
    
    // 检查全局互斥
    if (self.enableGlobalMutex && currentTime - s_lastGlobalActionTime < self.antiShakeInterval) {
        return NO;
    }
    
    return YES;
}

/// 更新操作时间
- (void)updateActionTime {
    NSTimeInterval currentTime = [[NSDate date] timeIntervalSince1970];
    self.lastActionTime = currentTime;
    if (self.enableGlobalMutex) {
        s_lastGlobalActionTime = currentTime;
    }
}

/// 处理值变化事件
- (void)handleValueChanged:(ZLAntiShakeSwitch *)sender {
    if (self.isHandlingValueChange) {
        return; // 防止递归调用
    }
    
    // 执行自定义回调
    if (self.valueChangedBlock) {
        self.valueChangedBlock(self, self.isOn);
    }
}

/// 显示防呆反馈（可选的视觉提示）
- (void)showAntiShakeFeedback {
    // 简单的视觉反馈：短暂改变透明度
    [UIView animateWithDuration:0.1 animations:^{
        self.alpha = 0.5;
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:0.1 animations:^{
            self.alpha = 1.0;
        }];
    }];
}

#pragma mark - 公共方法

- (void)setValueChangedBlock:(void (^)(ZLAntiShakeSwitch *, BOOL))block {
    _valueChangedBlock = [block copy];
}

- (void)resetAntiShakeState {
    self.lastActionTime = 0;
}

+ (void)resetAllAntiShakeStates {
    s_lastGlobalActionTime = 0;
}

#pragma mark - 属性设置

- (void)setSwitchIdentifier:(NSString *)switchIdentifier {
    _switchIdentifier = [switchIdentifier copy];
}

- (void)setAntiShakeInterval:(NSTimeInterval)antiShakeInterval {
    _antiShakeInterval = MAX(0.1, antiShakeInterval); // 最小间隔0.1秒
}

#pragma mark - 调试信息

- (NSString *)description {
    return [NSString stringWithFormat:@"<%@: %p, identifier: %@, antiShakeInterval: %.1f, enableGlobalMutex: %@, isOn: %@>",
            NSStringFromClass([self class]),
            self,
            self.switchIdentifier ?: @"nil",
            self.antiShakeInterval,
            self.enableGlobalMutex ? @"YES" : @"NO",
            self.isOn ? @"YES" : @"NO"];
}

@end